/* Includes ----------------------------------------------------------*/
#include "module/module.h"
#include "infrared.h"

/* typedef -----------------------------------------------------------*/
/* define ------------------------------------------------------------*/
/* macro -------------------------------------------------------------*/
/* variables ---------------------------------------------------------*/
/* function prototypes -----------------------------------------------*/
void Infrare_DecodeXiaomi(struct Infrared *infrared);

/*********************************************************************************************/
// round off, the param is coef 
/********************************************************************************************/
int32_t RoundOff(int data, int param)
{
    return ((data % param) > (param / 2))? ((data / param + 1) * param) : (data / param) * param;
}
/*********************************************************************************************/
// infrared get the edge of signal 
/********************************************************************************************/
void Infrared_Trig(struct Infrared *infrared, bool isFalling, int32_t durationUs)
{
    /* finish high level */
    if(isFalling)
    {   infrared->listPluse[infrared->counter].high = RoundOff(durationUs, 100);   }
    /* finish low level */
    else
    {   infrared->listPluse[infrared->counter++].low = RoundOff(durationUs, 100);   }
    
#if defined(INFRARED_CODING_XIAOMI)
    Infrare_DecodeXiaomi(infrared);
#else
    
#endif
}
/*********************************************************************************************
 
 * name: 	Infrare_Handle
 * param: 	infrareObj
 * return: 	
 * remark: 	红外线处理
 
  ********************************************************************************************/
void Infrare_DecodeXiaomi(struct Infrared *infrared)
{
    int commandId = -1;
  
    if(infrared->counter == 13)
    {
        if(infrared->listPluse[0].low == 1000)
        {
            infrared->command = 0;
            for(int i=1; i<infrared->counter; i++)
            {
                infrared->command <<= 3;
                infrared->command |= infrared->listPluse[i].high / 300;
            }
            switch(infrared->command)
            {
            case 0x51389372E:
                commandId = INFRARED_COMMAND_UP;
                break;
            case 0x51389393A:
                commandId = INFRARED_COMMAND_DOWN;
                break;
            case 0x513894AF9:
                commandId = INFRARED_COMMAND_LEFT;
                break;
            case 0x5138954A9:
                commandId = INFRARED_COMMAND_RIGHT;
                break;
            case 0x5138956AE:
                commandId = INFRARED_COMMAND_CONFIRM;
                break;
            case 0x4AD555569:
                commandId = INFRARED_COMMAND_POWER;
                break;
            case 0x5138944E9:
                commandId = INFRARED_COMMAND_HOME;
                break;
            case 0x513893B3E:
                commandId = INFRARED_COMMAND_BACK;
                break;
            case 0x513893529:
                commandId = INFRARED_COMMAND_MENU;
                break;
            case 0x5138958B9:
                commandId = INFRARED_COMMAND_INCREASE;
                break;
            case 0x513895ABE:
                commandId = INFRARED_COMMAND_REDUCE;
                break;
            }
            if(infrared->Hook_ReceiveCommand != NULL)
            {   infrared->Hook_ReceiveCommand(commandId);   }
        }
        infrared->counter = 0;
    }
}
/*********************************************************************************************/
// Infrare_Reset
/********************************************************************************************/
void Infrared_Reset(struct Infrared *infrared)
{
    memset(infrared, 0, sizeof(struct Infrared));
}
